using System;
using Sys;
using System.Silverlight;
using seh = Sys.EventHandler;
using sea = Sys.EventArgs;
using System.Silverlight.Presentation;

namespace SBT
{
    public class NamedValueChangedEventArgs : sea
    {
        public string Name;
        public object OldValue;
        public object NewValue;
    }
    public delegate void NamedValueChangedEventHandler(object sender, NamedValueChangedEventArgs args);
    public class AgComponent : Component
    {

        public virtual void RaiseEvent(string name)
        {
            seh handler = (seh)Events.GetHandler(name);
            if ((bool)(object)handler)
                handler(this, sea.Empty);
        }
        private Dictionary m_namedValues = new Dictionary();
        public object GetNamedValue(string name)
        {
            return m_namedValues[name];
        }
        public void SetNamedValue(string name, object value)
        {
            if (m_namedValues[name] != value)
            {
                object old = m_namedValues[name];
                m_namedValues[name] = value;
                OnNamedValueChanged(name, old, value);
            }
        }
        protected virtual void OnNamedValueChanged(string name, object oldValue, object newValue)
        {
            NamedValueChangedEventHandler handler = (NamedValueChangedEventHandler)Events.GetHandler("namedValueChanged");
            if ((bool)(object)handler)
            {
                NamedValueChangedEventArgs args = new NamedValueChangedEventArgs();
                args.Name = name;
                args.OldValue = oldValue;
                args.NewValue = newValue;
                handler(this, args);
            }
        }
        public void add_namedValueChanged(NamedValueChangedEventHandler handler)
        {
            Events.AddHandler("namedValueChanged", handler);
        }
        public void remove_namedValueChanged(NamedValueChangedEventHandler handler)
        {
            Events.RemoveHandler("namedValueChanged", handler);
        }

        private SilverlightControl m_plugin;
        public SilverlightControl Plugin { get { return m_plugin; } set { m_plugin = value; } }
        public AgComponent()
        {
        }
        public override void Initialize()
        {
            base.Initialize();
            if (!(bool)(object)m_plugin)
            {
                throw Exception.InvalidOperation("AgComponent Plugin property not set.");
            }
        }
    }
    public class DBounds
    {
        public double Width;
        public double Height;
        public double Left;
        public double Top;
    }
    public class AgBehavior : AgComponent
    {

        private MultiBehavior m_multiBehavior;
        public MultiBehavior MultiBehavior
        {
            get
            {
                return m_multiBehavior;
            }
            set
            {
                m_multiBehavior = value;
            }
        }
        public double Width
        {
            get
            {
                try
                {
                    TextBlock asTb = (TextBlock)Element;
                    return asTb.ActualWidth;
                }
                catch
                {

                }
                return m_element.Width;
            }
            set
            {
                if (m_element.Width != value)
                {
                    m_element.Width = value;
                    if (MultiBehavior != null)
                        MultiBehavior.RaiseEvent("widthChanged");
                    else
                        RaiseEvent("widthChanged");
                }
            }
        }

        public void add_widthChanged(seh handler)
        {
            Events.AddHandler("widthChanged", handler);
        }
        public void remove_widthChanged(seh handler)
        {
            Events.RemoveHandler("widthChanged", handler);
        }

        public double Left
        {
            get
            {
                return (double)Element.GetValue("Canvas.Left");
            }
            set
            {
                Element.SetValue("Canvas.Left", value);
            }
        }
        public double Top
        {
            get
            {
                return (double)Element.GetValue("Canvas.Top");
            }
            set
            {
                Element.SetValue("Canvas.Top", value);
            }
        }


        public double Height
        {
            get
            {
                try
                {
                    TextBlock asTb = (TextBlock)Element;
                    return asTb.ActualHeight;
                }
                catch
                {

                }
                return m_element.Height;
            }
            set
            {
                if (m_element.Height != value)
                {
                    m_element.Height = value;
                    if (MultiBehavior != null)
                        MultiBehavior.RaiseEvent("heightChanged");
                    else
                        RaiseEvent("heightChanged");
                }
            }
        }

        public void add_heightChanged(seh handler)
        {
            Events.AddHandler("heightChanged", handler);
        }
        public void remove_heightChanged(seh handler)
        {
            Events.RemoveHandler("heightChanged", handler);
        }

        private static int s_lastGenerated = 0;

        public string ElementName { get { return Element.Name; } }
        private UIElement m_element;
        public UIElement Element { get { return m_element; } set { m_element = value; } }

        public static string GenerateName(SilverlightControl plugin)
        {
            do
            {
                string name = "__sct_generated_" + (++s_lastGenerated);
                try
                {
                    if(plugin.Content.FindName(name) == null)
                        return name;
                    
                }
                catch
                {
                    return name;
                }
            }
            while (true);
        }
        public AgBehavior()
        {


        }
        public override void Initialize()
        {
            if (!(bool)(object)s_behaviors)
                s_behaviors = new ArrayList();

            if (!(bool)(object)m_element)
            {
                throw Exception.InvalidOperation("The behavior host element is null");
            }
            UIElementBehaviorEntry entry = null;
            if (this.GetType() != typeof(MultiBehavior))
                entry = GetBehaviorFor(Element);
            if (entry == null)
            {
                entry = new UIElementBehaviorEntry();
                entry.Element = Element;
                entry.Behavior = this;
                ArrayList.Add(s_behaviors, entry);
            }
            else
            {

                AgBehavior current = entry.Behavior;
                if (current.GetType() == typeof(MultiBehavior))
                    ((MultiBehavior)current).AddBehavior(this);
                else
                {
                    MultiBehavior host = new MultiBehavior();
                    host.Plugin = this.Plugin;
                    host.Element = this.Element;
                    host.AddBehavior(current);
                    host.AddBehavior(this);
                    host.Initialize();
                }
            }

            base.Initialize();
        }
        public override void Dispose()
        {
            if (MultiBehavior != null)
                MultiBehavior.RemoveBehavior(this);
            else
            {
                UIElementBehaviorEntry entry = GetBehaviorFor(Element);
                if (entry != null)
                    ArrayList.Remove(s_behaviors, entry);
            }
            base.Dispose();

        }
        private static ArrayList s_behaviors;

        public static AgBehavior FindBehaviorByUIElement(UIElement element)
        {
            UIElementBehaviorEntry entry = GetBehaviorFor(element);
            if (entry != null)
                return entry.Behavior;
            return null;
        }
        public static UIElementBehaviorEntry GetBehaviorFor(System.Silverlight.Presentation.UIElement elem)
        {
            ArrayList list = s_behaviors;
            for (int i = 0; i < list.Length; i++)
            {
                if (((UIElementBehaviorEntry)list[i]).Element.Equals(elem))
                    return (UIElementBehaviorEntry)list[i];
            }
            return null;
        }
    }

    public class UIElementBehaviorEntry
    {
        public UIElement Element;
        public AgBehavior Behavior;
    }
}
